const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const { ApiResponse } = require('@shared/utils/response');
const mime = require('mime');

console.log('独立上传路由已加载');

// 确保上传目录存在
const UPLOAD_DIR = path.join(__dirname, '../../public/uploads');
const IMAGE_UPLOAD_DIR = path.join(UPLOAD_DIR, 'images');
const LOGO_UPLOAD_DIR = path.join(UPLOAD_DIR, 'logos');

console.log('上传目录配置:');
console.log('- 基本上传目录:', UPLOAD_DIR);
console.log('- 图片上传目录:', IMAGE_UPLOAD_DIR);
console.log('- Logo上传目录:', LOGO_UPLOAD_DIR);

// 确保目录存在
try {
  if (!fs.existsSync(UPLOAD_DIR)) {
    fs.mkdirSync(UPLOAD_DIR, { recursive: true });
    console.log(`创建上传根目录: ${UPLOAD_DIR}`);
  }
  
  if (!fs.existsSync(IMAGE_UPLOAD_DIR)) {
    fs.mkdirSync(IMAGE_UPLOAD_DIR, { recursive: true });
    console.log(`创建图片上传目录: ${IMAGE_UPLOAD_DIR}`);
  }
  
  if (!fs.existsSync(LOGO_UPLOAD_DIR)) {
    fs.mkdirSync(LOGO_UPLOAD_DIR, { recursive: true });
    console.log(`创建Logo上传目录: ${LOGO_UPLOAD_DIR}`);
  }
  
  // 检查目录权限
  fs.accessSync(UPLOAD_DIR, fs.constants.W_OK);
  console.log(`上传根目录可写: ${UPLOAD_DIR}`);
  
  fs.accessSync(IMAGE_UPLOAD_DIR, fs.constants.W_OK);
  console.log(`图片上传目录可写: ${IMAGE_UPLOAD_DIR}`);
  
  fs.accessSync(LOGO_UPLOAD_DIR, fs.constants.W_OK);
  console.log(`Logo上传目录可写: ${LOGO_UPLOAD_DIR}`);
} catch (error) {
  console.error('创建或检查上传目录权限失败:', error);
}

// 确保上传目录存在
const createUploadDir = (type = '') => {
  const dir = type ? path.join(UPLOAD_DIR, type) : UPLOAD_DIR;
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
    console.log(`创建上传目录: ${dir}`);
  }
  return dir;
};

// 确保基础目录存在
createUploadDir();
createUploadDir('images');
createUploadDir('files');
createUploadDir('logos');

// 配置 multer 存储
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    // 根据文件类型选择存储目录
    let uploadDir = UPLOAD_DIR;
    
    // 根据请求路径确定子目录
    if (req.originalUrl.includes('/logo')) {
      uploadDir = LOGO_UPLOAD_DIR;
    } else if (file.mimetype.startsWith('image/')) {
      uploadDir = IMAGE_UPLOAD_DIR;
    } else {
      uploadDir = path.join(UPLOAD_DIR, 'files');
    }
    
    cb(null, uploadDir);
  },
  filename: function (req, file, cb) {
    // 生成唯一文件名
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    const ext = path.extname(file.originalname);
    cb(null, uniqueSuffix + ext);
  }
});

// 文件过滤器
const fileFilter = (req, file, cb) => {
  // 允许的文件类型
  const allowedTypes = [
    'image/jpeg', 
    'image/png', 
    'image/gif', 
    'image/webp',
    'application/pdf',
    'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/vnd.ms-excel',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'text/plain'
  ];
  
  if (allowedTypes.includes(file.mimetype)) {
    cb(null, true);
  } else {
    cb(new Error('不支持的文件类型'), false);
  }
};

const upload = multer({
  storage: storage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 10 * 1024 * 1024 // 限制10MB
  }
});

// 获取上传的图片文件 - 通过文件名二进制访问
router.get('/get/:filename', (req, res) => {
  try {
    const { filename } = req.params;
    
    // 安全检查：防止文件遍历攻击
    if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
      return res.status(400).json(ApiResponse.error('非法的文件名'));
    }
    
    // 尝试在各个可能的目录中查找文件
    const possibleDirs = [
      path.join(UPLOAD_DIR, 'images'),
      path.join(UPLOAD_DIR, 'files'),
      path.join(UPLOAD_DIR, 'videos'),
      path.join(UPLOAD_DIR, 'audios'),
      UPLOAD_DIR // 根目录也检查
    ];
    
    // 找到文件的完整路径
    let filePath = null;
    let fileExists = false;
    
    for (const dir of possibleDirs) {
      const tempPath = path.join(dir, filename);
      if (fs.existsSync(tempPath)) {
        filePath = tempPath;
        fileExists = true;
        break;
      }
    }
    
    // 如果文件不存在
    if (!fileExists || !filePath) {
      console.error(`文件不存在: ${filename}`);
      return res.status(404).json(ApiResponse.error('文件不存在'));
    }
    
    // 获取文件信息
    const stat = fs.statSync(filePath);
    
    // 获取文件的MIME类型
    const mimeType = mime.lookup(filePath) || 'application/octet-stream';
    
    // 设置详细的CORS响应头，确保图片可以被跨域加载
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
    res.setHeader('Access-Control-Allow-Credentials', 'false');
    res.setHeader('Access-Control-Max-Age', '86400'); // 24小时
    
    // 设置缓存控制头
    res.setHeader('Cache-Control', 'public, max-age=86400'); // 24小时缓存
    res.setHeader('Pragma', 'public');
    
    // 设置响应头
    res.setHeader('Content-Type', mimeType);
    res.setHeader('Content-Length', stat.size);
    res.setHeader('Content-Disposition', `inline; filename=${encodeURIComponent(filename)}`);
    
    // 创建文件读取流并管道输出到响应
    const fileStream = fs.createReadStream(filePath);
    fileStream.pipe(res);
  } catch (error) {
    console.error('获取文件失败:', error);
    return res.status(500).json(ApiResponse.error('获取文件失败'));
  }
});

// 特定的Logo上传接口
router.post('/logo', (req, res, next) => {
  console.log('接收到Logo上传请求');
  
  // 使用 single 中间件处理单个 Logo 文件上传，字段名为 image
  const logoUpload = multer({
    storage: storage,
    fileFilter: (req, file, cb) => {
      // 只允许图片文件
      if (file.mimetype.startsWith('image/')) {
        cb(null, true);
      } else {
        cb(new Error('只能上传图片文件'), false);
      }
    },
    limits: {
      fileSize: 2 * 1024 * 1024 // 限制2MB
    }
  }).single('image');
  
  logoUpload(req, res, (err) => {
    if (err) {
      console.error('Logo上传错误:', err);
      return res.json(ApiResponse.error(err.message || 'Logo上传失败'));
    }
    
    try {
      if (!req.file) {
        console.log('没有接收到Logo文件');
        return res.json(ApiResponse.error('请选择要上传的Logo文件'));
      }
      
      const file = req.file;
      console.log('Logo文件信息:', file);
      
      // 构建访问URL
      const baseUrl = process.env.NODE_ENV === 'production'
        ? process.env.API_BASE_URL || 'https://api.example.com'
        : `http://localhost:${process.env.PORT || 3001}`;
      
      // 返回文件信息
      const fileInfo = {
        url: `${baseUrl}/uploads/logos/${file.filename}`,
        path: `/uploads/logos/${file.filename}`,
        name: file.originalname,
        size: file.size,
        type: file.mimetype
      };
      
      console.log('Logo上传成功,返回:', fileInfo);
      res.json(ApiResponse.success(fileInfo));
    } catch (error) {
      console.error('Logo处理失败:', error);
      res.json(ApiResponse.error(error.message || '处理Logo文件时出错'));
    }
  });
});

// 简单的单文件上传接口 - 无需认证
router.post('/simple', (req, res, next) => {
  console.log('接收到simple接口的文件上传请求');
  
  // 使用 any() 接受任何字段名，但限制最多只处理1个文件
  upload.any()(req, res, (err) => {
    if (err) {
      console.error('文件上传中间件错误:', err);
      return res.json(ApiResponse.error(err.message || '文件上传失败'));
    }
    
    try {
      console.log('开始处理文件上传');
      
      if (!req.files || req.files.length === 0) {
        console.log('没有接收到文件');
        return res.json(ApiResponse.error('请选择要上传的文件'));
      }

      // 只处理第一个文件，即使上传了多个
      const file = req.files[0];
      console.log('上传的文件信息:', file);

      // 构建访问URL
      const baseUrl = process.env.NODE_ENV === 'production'
        ? process.env.API_BASE_URL || 'https://api.example.com'
        : `http://localhost:${process.env.PORT || 3001}`;

      // 根据文件类型确定子目录
      const subDir = file.mimetype.startsWith('image/') ? 'images/' : 'files/';
      
      // 确保文件存储目录存在
      const targetDir = path.join(UPLOAD_DIR, subDir);
      if (!fs.existsSync(targetDir)) {
        console.log(`创建目录: ${targetDir}`);
        fs.mkdirSync(targetDir, { recursive: true });
      }
      
      // 检查文件是否已经移动到正确位置，如果不在正确位置则移动
      const expectedPath = path.join(targetDir, file.filename);
      const currentPath = file.path;
      
      if (currentPath !== expectedPath && fs.existsSync(currentPath)) {
        console.log(`将文件从 ${currentPath} 移动到 ${expectedPath}`);
        try {
          // 如果目标文件已存在，先删除
          if (fs.existsSync(expectedPath)) {
            fs.unlinkSync(expectedPath);
          }
          // 复制文件到正确位置
          fs.copyFileSync(currentPath, expectedPath);
          // 删除原文件
          fs.unlinkSync(currentPath);
          // 更新文件路径
          file.path = expectedPath;
          console.log('文件已移动到正确位置');
        } catch (moveError) {
          console.error('移动文件失败:', moveError);
          // 继续处理，不中断流程
        }
      }

      // API访问路径
      const apiUrl = `${baseUrl}/api/upload/get/${file.filename}`;
      
      // 构建返回的文件信息，确保URL/路径格式统一
      const fileInfo = {
        // apiUrl是首选的访问方式，通过API路径访问以支持CORS
        apiUrl: apiUrl,
        // 为兼容性保留直接URL，但前端应优先使用apiUrl
        url: apiUrl,
        // 也保留旧版direct_url
        direct_url: `${baseUrl}/uploads/${subDir}${file.filename}`,
        // path是相对路径，前端可与origin拼接成完整URL
        path: `/uploads/${subDir}${file.filename}`,
        filename: file.filename,
        name: file.originalname,
        size: file.size,
        type: file.mimetype
      };

      // 验证文件是否可以通过URL访问
      const fileUrl = fileInfo.url;
      console.log('文件应该可以通过以下URL访问:');
      console.log(`1. ${fileInfo.apiUrl} (通过API访问，推荐方式)`);
      console.log(`2. ${fileInfo.direct_url} (直接访问，可能有CORS问题)`);
      
      console.log('上传成功,返回信息:', fileInfo);
      res.json(ApiResponse.success(fileInfo));
    } catch (error) {
      console.error('上传处理过程中出错:', error);
      res.json(ApiResponse.error(error.message || '处理文件时出错'));
    }
  });
});

// 多文件上传接口 - 无需认证，接受最多5个文件
router.post('/multiple', (req, res, next) => {
  // 限制最多接受5个文件
  upload.array('files', 5)(req, res, (err) => {
    if (err) {
      // 如果错误是因为字段名不匹配，尝试使用any()接受任何字段的文件
      if (err.code === 'LIMIT_UNEXPECTED_FILE') {
        console.log('字段名不匹配，尝试接受任何字段的文件');
        return upload.any()(req, res, (err2) => {
          if (err2) {
            console.error('第二次尝试上传失败:', err2);
            return res.json(ApiResponse.error(err2.message || '文件上传失败'));
          }
          handleMultipleFiles(req, res);
        });
      }
      
      console.error('文件上传中间件错误:', err);
      return res.json(ApiResponse.error(err.message || '文件上传失败'));
    }
    
    handleMultipleFiles(req, res);
  });
});

// 处理多文件上传的函数
function handleMultipleFiles(req, res) {
  try {
    console.log('接收到多文件上传请求');
    
    if (!req.files || req.files.length === 0) {
      console.log('没有接收到文件');
      return res.json(ApiResponse.error('请选择要上传的文件'));
    }

    console.log(`接收到 ${req.files.length} 个文件`);

    // 构建访问URL
    const baseUrl = process.env.NODE_ENV === 'production'
      ? process.env.API_BASE_URL || 'https://api.example.com'
      : `http://localhost:${process.env.PORT || 3001}`;

    // 返回所有文件信息
    const filesInfo = req.files.map(file => {
      // 根据文件类型确定子目录
      const subDir = file.mimetype.startsWith('image/') ? 'images/' : 'files/';
      
      return {
        url: `${baseUrl}/uploads/${subDir}${file.filename}`,
        path: `/uploads/${subDir}${file.filename}`,
        name: file.originalname,
        size: file.size,
        type: file.mimetype
      };
    });

    console.log('多文件上传成功');
    res.json(ApiResponse.success(filesInfo));
  } catch (error) {
    console.error('多文件上传失败:', error);
    res.json(ApiResponse.error(error.message || '处理文件时出错'));
  }
}

// 错误处理中间件
router.use((error, req, res, next) => {
  console.error('上传路由错误:', error);
  
  if (error instanceof multer.MulterError) {
    // multer 错误
    if (error.code === 'LIMIT_FILE_SIZE') {
      return res.json(ApiResponse.error('文件大小超出限制'));
    }
    return res.json(ApiResponse.error(error.message));
  }
  
  // 其他错误
  res.json(ApiResponse.error(error.message));
});

// 调试路由 - 检查文件系统状态
router.get('/debug', async (req, res) => {
  try {
    const debugInfo = {
      timestamp: new Date().toISOString(),
      environment: process.env.NODE_ENV || 'development',
      directories: {},
      testFile: {}
    };
    
    // 检查各个目录是否存在
    const dirsToCheck = [
      { name: 'uploadRoot', path: UPLOAD_DIR },
      { name: 'images', path: IMAGE_UPLOAD_DIR },
      { name: 'files', path: path.join(UPLOAD_DIR, 'files') },
      { name: 'videos', path: path.join(UPLOAD_DIR, 'videos') },
      { name: 'audios', path: path.join(UPLOAD_DIR, 'audios') },
      { name: 'logos', path: LOGO_UPLOAD_DIR }
    ];
    
    for (const dir of dirsToCheck) {
      const dirInfo = {
        path: dir.path,
        exists: false,
        isDirectory: false,
        readable: false,
        writable: false,
        fileCount: 0,
        files: []
      };
      
      try {
        // 检查目录是否存在
        dirInfo.exists = fs.existsSync(dir.path);
        
        if (dirInfo.exists) {
          // 检查是否是目录
          const stats = fs.statSync(dir.path);
          dirInfo.isDirectory = stats.isDirectory();
          
          // 检查权限
          try {
            fs.accessSync(dir.path, fs.constants.R_OK);
            dirInfo.readable = true;
          } catch (e) {
            dirInfo.readable = false;
          }
          
          try {
            fs.accessSync(dir.path, fs.constants.W_OK);
            dirInfo.writable = true;
          } catch (e) {
            dirInfo.writable = false;
          }
          
          // 获取文件列表
          if (dirInfo.isDirectory && dirInfo.readable) {
            const files = fs.readdirSync(dir.path);
            dirInfo.fileCount = files.length;
            dirInfo.files = files.slice(0, 20); // 只返回前20个文件名
          }
        }
      } catch (error) {
        dirInfo.error = error.message;
      }
      
      debugInfo.directories[dir.name] = dirInfo;
    }
    
    // 尝试写入、读取和删除测试文件
    const testFilePath = path.join(UPLOAD_DIR, `test-${Date.now()}.txt`);
    
    try {
      // 写入测试
      fs.writeFileSync(testFilePath, 'Hello, this is a test file to check write permissions.');
      debugInfo.testFile.writeSuccess = true;
      
      // 读取测试
      const content = fs.readFileSync(testFilePath, 'utf8');
      debugInfo.testFile.readSuccess = true;
      debugInfo.testFile.contentLength = content.length;
      
      // 删除测试
      fs.unlinkSync(testFilePath);
      debugInfo.testFile.deleteSuccess = true;
    } catch (error) {
      debugInfo.testFile.error = error.message;
    }
    
    // 返回调试信息
    return res.json({
      code: 0,
      message: '调试信息',
      data: debugInfo
    });
  } catch (error) {
    console.error('生成调试信息失败:', error);
    return res.status(500).json(ApiResponse.error('生成调试信息失败'));
  }
});

// 处理单个图片上传
router.post('/image', upload.single('file'), (req, res) => {
  try {
    console.log('收到图片上传请求:', {
      headers: req.headers,
      body: req.body,
      method: req.method,
      url: req.originalUrl
    });

    if (!req.file) {
      console.error('未接收到文件');
      return res.status(400).json(ApiResponse.error('未接收到文件'));
    }

    console.log('文件信息:', req.file);
    const { filename, originalname, mimetype, size, path: filePath, destination } = req.file;

    // 确保文件已保存到磁盘并可读
    let fileExists = false;
    let fileSize = 0;
    let readSuccess = false;

    try {
      const fullPath = path.join(destination, filename);
      const stats = fs.statSync(fullPath);
      fileExists = true;
      fileSize = stats.size;

      // 尝试读取文件内容头部确认文件可读
      const buffer = Buffer.alloc(100); // 读取前100字节
      const fd = fs.openSync(fullPath, 'r');
      fs.readSync(fd, buffer, 0, 100, 0);
      fs.closeSync(fd);
      readSuccess = true;
    } catch (error) {
      console.error('验证上传文件失败:', error);
    }

    // 构建访问URL
    const isProduction = process.env.NODE_ENV === 'production';
    const baseUrl = isProduction 
      ? req.headers.origin || req.protocol + '://' + req.get('host')
      : 'http://localhost:3001';

    // 确定文件类型的子目录
    let subdirectory = 'images';
    if (mimetype.startsWith('image/')) {
      subdirectory = 'images';
    } else if (mimetype.startsWith('video/')) {
      subdirectory = 'videos';
    } else if (mimetype.startsWith('audio/')) {
      subdirectory = 'audios';
    } else {
      subdirectory = 'files';
    }

    // 构建API访问URL和传统文件URL
    const apiUrl = `/api/upload/get/${filename}`; // API方式访问
    const fileUrl = `/public/uploads/${subdirectory}/${filename}`; // 传统文件路径

    // 返回响应
    return res.json({
      code: 0,
      message: '上传成功',
      data: {
        name: originalname,
        url: fileUrl, // 传统访问路径(兼容)
        apiUrl: apiUrl, // API访问路径(新方法)
        size,
        type: mimetype,
        filename, // 保存的文件名(带扩展名)
        // 调试信息
        debug: {
          fileExists,
          fileSize,
          readSuccess,
          destination,
          subdirectory,
          fullpath: path.join(destination, filename)
        }
      }
    });
  } catch (error) {
    console.error('处理图片上传请求失败:', error);
    return res.status(500).json(ApiResponse.error(error.message || '上传处理失败'));
  }
});

// 处理单个文件上传
router.post('/file', upload.single('file'), (req, res) => {
  try {
    console.log('收到文件上传请求:', {
      headers: req.headers,
      body: req.body,
      method: req.method,
      url: req.originalUrl
    });

    if (!req.file) {
      console.error('未接收到文件');
      return res.status(400).json(ApiResponse.error('未接收到文件'));
    }

    console.log('文件信息:', req.file);
    const { filename, originalname, mimetype, size, path: filePath, destination } = req.file;

    // 确保文件已保存到磁盘并可读
    let fileExists = false;
    let fileSize = 0;
    let readSuccess = false;

    try {
      const fullPath = path.join(destination, filename);
      const stats = fs.statSync(fullPath);
      fileExists = true;
      fileSize = stats.size;

      // 尝试读取文件内容头部确认文件可读
      const buffer = Buffer.alloc(100); // 读取前100字节
      const fd = fs.openSync(fullPath, 'r');
      fs.readSync(fd, buffer, 0, 100, 0);
      fs.closeSync(fd);
      readSuccess = true;
    } catch (error) {
      console.error('验证上传文件失败:', error);
    }

    // 构建访问URL
    const isProduction = process.env.NODE_ENV === 'production';
    const baseUrl = isProduction 
      ? req.headers.origin || req.protocol + '://' + req.get('host')
      : 'http://localhost:3001';

    // 构建API访问URL和传统文件URL
    const apiUrl = `/api/upload/get/${filename}`; // API方式访问
    const fileUrl = `/public/uploads/files/${filename}`; // 传统文件路径

    // 返回响应
    return res.json({
      code: 0,
      message: '上传成功',
      data: {
        name: originalname,
        url: fileUrl, // 传统访问路径(兼容)
        apiUrl: apiUrl, // API访问路径(新方法)
        size,
        type: mimetype,
        filename, // 保存的文件名(带扩展名)
        // 调试信息
        debug: {
          fileExists,
          fileSize,
          readSuccess,
          destination,
          fullpath: path.join(destination, filename)
        }
      }
    });
  } catch (error) {
    console.error('处理文件上传请求失败:', error);
    return res.status(500).json(ApiResponse.error(error.message || '上传处理失败'));
  }
});

// 处理轮播图上传
router.post('/banner', upload.single('file'), (req, res) => {
  try {
    console.log('收到轮播图上传请求:', {
      headers: req.headers,
      body: req.body,
      method: req.method,
      url: req.originalUrl
    });

    if (!req.file) {
      console.error('未接收到文件');
      return res.status(400).json(ApiResponse.error('未接收到文件'));
    }

    console.log('轮播图文件信息:', req.file);
    const { filename, originalname, mimetype, size, path: filePath, destination } = req.file;

    // 确保文件已保存到磁盘并可读
    try {
      const fullPath = path.join(destination, filename);
      const stats = fs.statSync(fullPath);
      
      // 构建访问URL
      const isProduction = process.env.NODE_ENV === 'production';
      const baseUrl = isProduction 
        ? req.headers.origin || req.protocol + '://' + req.get('host')
        : 'http://localhost:3001';

      // 构建文件URL
      const fileUrl = `/public/uploads/images/${filename}`;

      // 返回响应
      return res.json({
        code: 200,
        message: '上传成功',
        data: {
          url: fileUrl,
          name: originalname,
          size,
          type: mimetype
        }
      });
    } catch (error) {
      console.error('验证上传文件失败:', error);
      return res.status(500).json(ApiResponse.error('文件验证失败'));
    }
  } catch (error) {
    console.error('处理轮播图上传请求失败:', error);
    return res.status(500).json(ApiResponse.error(error.message || '上传处理失败'));
  }
});

module.exports = router; 